package org.example;

import java.lang.annotation.*;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class Main {
//1.自定义注解
    @Target({ElementType.METHOD,ElementType.TYPE})//用于类和方法
    @Retention(RetentionPolicy.RUNTIME)//运行时保留
    @Inherited//父类的注解被子类继承
    @interface MyAnnotation {
        String value() default "default value";
        int priority() default 0;
    }

//    2.父类（使用自定义注解）
    @MyAnnotation(value = "父类",priority = 1)
    static class ParentClass {
        public void doSomething() {
            System.out.println("父类 doSomething");
        }
    }
//    子类（继承父类，会继承 @MyAnnotation）
static class ChildClass extends ParentClass{
        //子类重写父类方法
    @Override
    public void doSomething() {
        System.out.println("子类重写 doSomething");
    }
    @Deprecated
    public void oldMethod() {
        System.out.println("即将被弃的方法");
    }
    @SuppressWarnings("unchecked")
    public void unsafeOperation() {
        List list = new ArrayList();
//        明确泛型写法： List<String> list = new ArrayList<>();
        list.add("Hello");
        List<String> stringList = list; // unchecked 警告被抑制
        System.out.println(stringList.get(0));
    }
    @MyAnnotation(value = "重要方法",priority = 5)
    public void importantTask(){
        System.out.println("在方法上使用自定义注解");
    }

}
    //主类：反射读取注解
    static class AnnotationDemo{
        public void run() throws Exception {
            ChildClass child=new ChildClass();
//            调用子类方法
            child.doSomething();
            child.oldMethod();
            child.unsafeOperation();
            child.importantTask();
//            使用反射读取注解
        Class<ChildClass> clazz=ChildClass.class;
//      读取类上的 @MyAnnotation（因为 @Inherited，子类继承了父类的注解）
        if(clazz.isAnnotationPresent(MyAnnotation.class)){
            MyAnnotation classAnno=clazz.getAnnotation(MyAnnotation.class);
            System.out.println("Class annotation value: " + classAnno.value());
            System.out.println("Class annotation priority: " + classAnno.priority());
        }
//         读取方法上的 @MyAnnotation
            Method method=clazz.getMethod("importantTask");
            if(method.isAnnotationPresent(MyAnnotation.class)){
                MyAnnotation methodAnno = method.getAnnotation(MyAnnotation.class);
                System.out.println("Method annotation value: " + methodAnno.value());
                System.out.println("Method annotation priority: " + methodAnno.priority());
            }
        }
    }
    public static void main(String[] args) {
        try{
            new AnnotationDemo().run();
        }
        catch (Exception e){
            e.printStackTrace();
        }

        }
}
